package com.jacobson.huobi.components.header

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Handler
import android.text.Editable
import android.text.TextWatcher
import android.text.format.DateFormat
import android.util.AttributeSet
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import com.jacobson.core.utils.AppUtils
import com.jacobson.core.utils.SoftInputMethodManager
import com.jacobson.core.widget.logger.LoggerFactory
import com.jacobson.core.widget.storage.GlobalStorage
import com.jacobson.huobi.Constants
import com.jacobson.huobi.Constants.KEY_SYSTEM_STATUS
import com.jacobson.huobi.R
import com.jacobson.huobi.entities.SystemActiveInfo
import com.jacobson.huobi.entities.events.SystemActiveEvent
import com.jacobson.huobi.entities.events.UpdateEvent
import kotlinx.android.synthetic.main.popup_breathing_light.view.*
import kotlinx.android.synthetic.main.view_common_search_header.view.*
import org.simple.eventbus.EventBus
import org.simple.eventbus.Subscriber


/**
 * ================================================
 *  通用头
 *  @author Wucz on 2018/7/23 21:17
 * ================================================
 */

class CommonSearchHeader(
    context: Context?, attrs: AttributeSet?, defStyleAttr: Int
) : LinearLayout(context, attrs, defStyleAttr), TextWatcher {
    private val logger = LoggerFactory.getLogger()
    private var listener: OnConstraintChangedListener? = null
    private val eventHandler = Handler()
    private var oldConstraint = ""
    private var onEditorActionListener: ((v: TextView, actionId: Int, event: KeyEvent?) -> Boolean)? =
        null
    private var forcePadding = false
    private var measurePaddingTop = 0
    private var searchHint: String? = null
    private var keyword: String? = null
    private var delayMillis: Long = 1000

    private val searchConstraintsEvent = Runnable {
        logger.d("searchConstraintsEvent is Changed$oldConstraint")
        commonHeaderEtSearch.text.toString().takeIf { it != oldConstraint }?.run {
            listener?.let {
                it.onConstraintChanged(this)
                oldConstraint = this
            }
        }
    }
    constructor(context: Context) : this(context, null)

    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)


    override fun onFinishInflate() {
        super.onFinishInflate()
        LayoutInflater.from(context).inflate(R.layout.view_common_search_header, this, true)
        commonHeaderEtSearch.addTextChangedListener(this)
        commonHeaderEtSearch.setOnEditorActionListener { v, actionId, event ->
            if (GlobalStorage.get(Constants.KEY_IS_MAIN_FRONT) == true) {
                keyword = commonHeaderEtSearch.text.trim().toString()
                EventBus.getDefault().post(UpdateEvent(keyword, true))
            }
            onEditorActionListener?.invoke(v, actionId, event) ?: false
        }
        commonHeaderEtSearch.setText(keyword)

//        commonHeaderEtSearch.setOnClickListener{
//            SymbolSearchActivity.startActivity(this.context)
//        }
//        commonHeaderEtSearch.setOnFocusChangeListener { _, b ->
//            if (b) {
//                SymbolSearchActivity.startActivity(this.context)
//            }
//        }
//                SymbolSearchActivity.startActivity(this.context)

        searchHint?.let { setSearchHint(it) }
        breathingLightView.setOnClickListener {
            val systemStatus: List<SystemActiveInfo> = GlobalStorage.get(KEY_SYSTEM_STATUS) as List<SystemActiveInfo>
            PopupWindow(this).apply {
                width = ViewGroup.LayoutParams.WRAP_CONTENT
                height = ViewGroup.LayoutParams.WRAP_CONTENT
                contentView =
                    LayoutInflater.from(context).inflate(R.layout.popup_breathing_light, null)
                setBackgroundDrawable(ColorDrawable(Color.parseColor("#BB000000")))
                isOutsideTouchable = false
                isFocusable = true
                contentView.breathingLightInfo.text =
                    context.getString(R.string.tip_breathing_light_format)
                        .format(
                            showStatus(systemStatus, 0),
                            showStatus(systemStatus, 1),
                            showStatus(systemStatus, 2),
                            showStatus(systemStatus, 3),
                            showStatus(systemStatus, 4),
                            showStatus(systemStatus, 5)
                        )
            }.showAsDropDown(breathingLightView)
        }
    }

    private fun showStatus(systemStatus: List<SystemActiveInfo>, index: Int): String {
        if (systemStatus.isNullOrEmpty() || systemStatus.size <= index) {
            return "未连接"
        }
        val ts = DateFormat.format("yyyy-MM-dd HH:mm:ss", systemStatus[index].lastTs * 1000)
        return if (systemStatus[index].status == 1) "已连接: $ts" else "未连接: $ts"
    }

    fun setOnEditorActionListener(listener: ((v: TextView, actionId: Int, event: KeyEvent?) -> Boolean)? = null) {
        this.onEditorActionListener = listener
    }

    fun setOnConstraintChangedListener(
        listener: OnConstraintChangedListener,
        delayMillis: Long = 1000
    ) {
        this.delayMillis = delayMillis
        this.listener = listener
    }

    override fun afterTextChanged(s: Editable?) {
        eventHandler.removeCallbacks(searchConstraintsEvent)
        eventHandler.postDelayed(searchConstraintsEvent, delayMillis)
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        if (GlobalStorage.get(Constants.KEY_IS_MAIN_FRONT) == true) {
            keyword = commonHeaderEtSearch.text.trim().toString()
            EventBus.getDefault().post(UpdateEvent(keyword, true))
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        eventHandler.removeCallbacks(searchConstraintsEvent)
    }


    fun setSearchClickListener(clickListener: () -> Unit) {
        abandonFocus()
        commonHeaderEtSearch.setOnClickListener {
            clickListener.invoke()
        }
    }

    fun abandonFocus() {
        hadFocus = false
        SoftInputMethodManager.hide(context, commonHeaderEtSearch)
        commonHeaderEtSearch.isFocusable = false
        commonHeaderEtSearch.isFocusableInTouchMode = false
    }

    fun requestSearchFocus() {
        hadFocus = true
        commonHeaderEtSearch.isFocusableInTouchMode = true
        commonHeaderEtSearch.isFocusable = true
        commonHeaderEtSearch.requestFocus()
        commonHeaderEtSearch.findFocus()
        SoftInputMethodManager.show(context, commonHeaderEtSearch)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var heightMeasure = heightMeasureSpec
        var paddingTopCus = paddingTop
        if (forcePadding) {
            measurePaddingTop = paddingTop
            val statusBarHeight = AppUtils.getStatusBarHeight(context)
            val height = MeasureSpec.getSize(heightMeasureSpec)
            val mode = MeasureSpec.getMode(heightMeasureSpec)
            paddingTopCus = statusBarHeight
            heightMeasure =
                MeasureSpec.makeMeasureSpec(height - measurePaddingTop + statusBarHeight, mode)
        }
        setPadding(paddingLeft, paddingTopCus, paddingRight, 0)
        super.onMeasure(widthMeasureSpec, heightMeasure)
    }

    private var hadFocus = false
    fun isInFocus() = hadFocus

    fun getConstraint(): String {
        return commonHeaderEtSearch.text.toString()
    }

    fun setForcePadding(forcePadding: Boolean = true) {
        this.forcePadding = forcePadding
    }

    fun setSearchHint(hint: String) {
        this.searchHint = hint
        this.commonHeaderEtSearch?.hint = searchHint
    }

    fun updateSystemStatus(data: List<SystemActiveInfo>) {
        breathingLightView.update(data)
    }

    interface OnConstraintChangedListener {
        fun onConstraintChanged(constraint: String)
    }
}